/*
 * RamStorageView.java
 */
package ramstorage;

import java.awt.BorderLayout;
import java.util.Observable;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jdesktop.application.Action;
import org.jdesktop.application.ResourceMap;
import org.jdesktop.application.SingleFrameApplication;
import org.jdesktop.application.FrameView;
import org.jdesktop.application.TaskMonitor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import javax.swing.Timer;
import javax.swing.Icon;
import javax.swing.JDialog;
import javax.swing.JFrame;
import java.util.Map;
import java.util.Observer;
import java.util.SortedMap;
import java.util.TreeMap;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.data.time.Minute;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import thesis.ramstorage.application.DataObj;
import thesis.ramstorage.application.NetworkControl;
import thesis.ramstorage.application.RealSimulator;
import thesis.ramstorage.application.SystemConfiguration;
import thesis.ramstorage.core.Fallible;
import thesis.ramstorage.core.PhysicalNode;
import thesis.ramstorage.core.VirtualNode;
import thesis.ramstorage.math.StatisticParameters;
import thesis.ramstorage.util.ChartRender;
import thesis.ramstorage.util.EvaluatedParameters;
import thesis.ramstorage.util.Util;
import thesis.ramstorage.util.NodeParameters;

/**
 * The application's main frame.
 */
public class RamStorageView extends FrameView implements Observer{

    private long identityIdx;
    private List<StatisticParameters> statsKeepTrack= new ArrayList<StatisticParameters>();
    
    public RamStorageView(SingleFrameApplication app) {
        super(app);

        initComponents();

        // status bar initialization - message timeout, idle icon and busy animation, etc
        ResourceMap resourceMap = getResourceMap();
        int messageTimeout = resourceMap.getInteger("StatusBar.messageTimeout");
        messageTimer = new Timer(messageTimeout, new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                statusMessageLabel.setText("");
            }
        });
        messageTimer.setRepeats(false);
        int busyAnimationRate = resourceMap.getInteger("StatusBar.busyAnimationRate");
        for (int i = 0; i < busyIcons.length; i++) {
            busyIcons[i] = resourceMap.getIcon("StatusBar.busyIcons[" + i + "]");
        }
        busyIconTimer = new Timer(busyAnimationRate, new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                busyIconIndex = (busyIconIndex + 1) % busyIcons.length;
                statusAnimationLabel.setIcon(busyIcons[busyIconIndex]);
            }
        });
        idleIcon = resourceMap.getIcon("StatusBar.idleIcon");
        statusAnimationLabel.setIcon(idleIcon);
        progressBar.setVisible(false);

        // connecting action tasks to status bar via TaskMonitor
        TaskMonitor taskMonitor = new TaskMonitor(getApplication().getContext());
        taskMonitor.addPropertyChangeListener(new java.beans.PropertyChangeListener() {

            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                String propertyName = evt.getPropertyName();
                if ("started".equals(propertyName)) {
                    if (!busyIconTimer.isRunning()) {
                        statusAnimationLabel.setIcon(busyIcons[0]);
                        busyIconIndex = 0;
                        busyIconTimer.start();
                    }
                    progressBar.setVisible(true);
                    progressBar.setIndeterminate(true);
                } else if ("done".equals(propertyName)) {
                    busyIconTimer.stop();
                    statusAnimationLabel.setIcon(idleIcon);
                    progressBar.setVisible(false);
                    progressBar.setValue(0);
                } else if ("message".equals(propertyName)) {
                    String text = (String) (evt.getNewValue());
                    statusMessageLabel.setText((text == null) ? "" : text);
                    messageTimer.restart();
                } else if ("progress".equals(propertyName)) {
                    int value = (Integer) (evt.getNewValue());
                    progressBar.setVisible(true);
                    progressBar.setIndeterminate(false);
                    progressBar.setValue(value);
                }
            }
        });
    }

    @Action
    public void showAboutBox() {
        if (aboutBox == null) {
            JFrame mainFrame = RamStorageApp.getApplication().getMainFrame();
            aboutBox = new RamStorageAboutBox(mainFrame);
            aboutBox.setLocationRelativeTo(mainFrame);
        }
        RamStorageApp.getApplication().show(aboutBox);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        mainPanel = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        consoleTextArea = new javax.swing.JTextArea();
        jLabel1 = new javax.swing.JLabel();
        viewNetInforButton = new javax.swing.JButton();
        evaluateButton = new javax.swing.JButton();
        ServerList = new javax.swing.JComboBox();
        jLabel2 = new javax.swing.JLabel();
        shutdownNodeButton = new javax.swing.JButton();
        jButton5 = new javax.swing.JButton();
        initializeButton = new javax.swing.JButton();
        clearButton = new javax.swing.JButton();
        tabbedPane = new javax.swing.JTabbedPane();
        netInforPanel = new javax.swing.JPanel();
        jScrollPane2 = new javax.swing.JScrollPane();
        netInforTable = new javax.swing.JTable();
        jPanel2 = new javax.swing.JPanel();
        jScrollPane3 = new javax.swing.JScrollPane();
        vNodeTable = new javax.swing.JTable();
        chartPanel = new javax.swing.JPanel();
        timeLineChartPanel = new javax.swing.JPanel();
        rebootButton = new javax.swing.JButton();
        netStatusText = new javax.swing.JTextField();
        jLabel3 = new javax.swing.JLabel();
        jButton1 = new javax.swing.JButton();
        numberOfKeys = new javax.swing.JTextField();
        jLabel4 = new javax.swing.JLabel();
        menuBar = new javax.swing.JMenuBar();
        javax.swing.JMenu fileMenu = new javax.swing.JMenu();
        javax.swing.JMenuItem exitMenuItem = new javax.swing.JMenuItem();
        javax.swing.JMenu helpMenu = new javax.swing.JMenu();
        javax.swing.JMenuItem aboutMenuItem = new javax.swing.JMenuItem();
        statusPanel = new javax.swing.JPanel();
        javax.swing.JSeparator statusPanelSeparator = new javax.swing.JSeparator();
        statusMessageLabel = new javax.swing.JLabel();
        statusAnimationLabel = new javax.swing.JLabel();
        progressBar = new javax.swing.JProgressBar();

        mainPanel.setName("mainPanel"); // NOI18N

        jScrollPane1.setName("jScrollPane1"); // NOI18N

        consoleTextArea.setColumns(20);
        consoleTextArea.setRows(5);
        consoleTextArea.setName("consoleTextArea"); // NOI18N
        jScrollPane1.setViewportView(consoleTextArea);

        org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(ramstorage.RamStorageApp.class).getContext().getResourceMap(RamStorageView.class);
        jLabel1.setText(resourceMap.getString("jLabel1.text")); // NOI18N
        jLabel1.setName("jLabel1"); // NOI18N

        javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(ramstorage.RamStorageApp.class).getContext().getActionMap(RamStorageView.class, this);
        viewNetInforButton.setAction(actionMap.get("viewNetInfor")); // NOI18N
        viewNetInforButton.setText(resourceMap.getString("viewNetInforButton.text")); // NOI18N
        viewNetInforButton.setName("viewNetInforButton"); // NOI18N

        evaluateButton.setAction(actionMap.get("evaluate")); // NOI18N
        evaluateButton.setText(resourceMap.getString("evaluateButton.text")); // NOI18N
        evaluateButton.setName("evaluateButton"); // NOI18N

        ServerList.setName("ServerList"); // NOI18N

        jLabel2.setText(resourceMap.getString("jLabel2.text")); // NOI18N
        jLabel2.setName("jLabel2"); // NOI18N

        shutdownNodeButton.setAction(actionMap.get("shutdownNode")); // NOI18N
        shutdownNodeButton.setText(resourceMap.getString("shutdownNodeButton.text")); // NOI18N
        shutdownNodeButton.setName("shutdownNodeButton"); // NOI18N

        jButton5.setAction(actionMap.get("joinNode")); // NOI18N
        jButton5.setText(resourceMap.getString("jButton5.text")); // NOI18N
        jButton5.setName("jButton5"); // NOI18N

        initializeButton.setAction(actionMap.get("initialize")); // NOI18N
        initializeButton.setText(resourceMap.getString("initialize.text")); // NOI18N
        initializeButton.setActionCommand(resourceMap.getString("initialize.actionCommand")); // NOI18N
        initializeButton.setName("initialize"); // NOI18N
        initializeButton.setOpaque(false);

        clearButton.setAction(actionMap.get("clearConsole")); // NOI18N
        clearButton.setText(resourceMap.getString("clearButton.text")); // NOI18N
        clearButton.setName("clearButton"); // NOI18N

        tabbedPane.setName("tabbedPane"); // NOI18N

        netInforPanel.setName("netInforPanel"); // NOI18N

        jScrollPane2.setName("jScrollPane2"); // NOI18N

        netInforTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null, null, null, null, null},
                {null, null, null, null, null, null},
                {null, null, null, null, null, null},
                {null, null, null, null, null, null},
                {null, null, null, null, null, null},
                {null, null, null, null, null, null},
                {null, null, null, null, null, null},
                {null, null, null, null, null, null},
                {null, null, null, null, null, null},
                {null, null, null, null, null, null},
                {null, null, null, null, null, null},
                {null, null, null, null, null, null},
                {null, null, null, null, null, null},
                {null, null, null, null, null, null},
                {null, null, null, null, null, null},
                {null, null, null, null, null, null},
                {null, null, null, null, null, null},
                {null, null, null, null, null, null},
                {null, null, null, null, null, null},
                {null, null, null, null, null, null},
                {null, null, null, null, null, null},
                {null, null, null, null, null, null},
                {null, null, null, null, null, null},
                {null, null, null, null, null, null},
                {null, null, null, null, null, null},
                {null, null, null, null, null, null},
                {null, null, null, null, null, null},
                {null, null, null, null, null, null},
                {null, null, null, null, null, null},
                {null, null, null, null, null, null}
            },
            new String [] {
                "ID", "Status", "Load", "Number of vNode", "vNode keys", "AverageLoad"
            }
        ) {
            Class[] types = new Class [] {
                java.lang.Long.class, java.lang.String.class, java.lang.Long.class, java.lang.Integer.class, java.lang.String.class, java.lang.Double.class
            };
            boolean[] canEdit = new boolean [] {
                false, false, false, false, false, false
            };

            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        });
        netInforTable.setName("netInforTable"); // NOI18N
        jScrollPane2.setViewportView(netInforTable);

        javax.swing.GroupLayout netInforPanelLayout = new javax.swing.GroupLayout(netInforPanel);
        netInforPanel.setLayout(netInforPanelLayout);
        netInforPanelLayout.setHorizontalGroup(
            netInforPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(netInforPanelLayout.createSequentialGroup()
                .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 765, Short.MAX_VALUE)
                .addContainerGap())
        );
        netInforPanelLayout.setVerticalGroup(
            netInforPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(netInforPanelLayout.createSequentialGroup()
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        );

        tabbedPane.addTab(resourceMap.getString("netInforPanel.TabConstraints.tabTitle"), netInforPanel); // NOI18N

        jPanel2.setName("jPanel2"); // NOI18N

        jScrollPane3.setName("jScrollPane3"); // NOI18N

        vNodeTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null},
                {null, null}
            },
            new String [] {
                "Key", "PNode"
            }
        ));
        vNodeTable.setName("vNodeTable"); // NOI18N
        jScrollPane3.setViewportView(vNodeTable);

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(296, Short.MAX_VALUE))
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        );

        tabbedPane.addTab(resourceMap.getString("jPanel2.TabConstraints.tabTitle"), jPanel2); // NOI18N

        chartPanel.setName("chartPanel"); // NOI18N

        javax.swing.GroupLayout chartPanelLayout = new javax.swing.GroupLayout(chartPanel);
        chartPanel.setLayout(chartPanelLayout);
        chartPanelLayout.setHorizontalGroup(
            chartPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 775, Short.MAX_VALUE)
        );
        chartPanelLayout.setVerticalGroup(
            chartPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 259, Short.MAX_VALUE)
        );

        tabbedPane.addTab(resourceMap.getString("chartPanel.TabConstraints.tabTitle"), chartPanel); // NOI18N

        timeLineChartPanel.setName("timeLineChartPanel"); // NOI18N

        javax.swing.GroupLayout timeLineChartPanelLayout = new javax.swing.GroupLayout(timeLineChartPanel);
        timeLineChartPanel.setLayout(timeLineChartPanelLayout);
        timeLineChartPanelLayout.setHorizontalGroup(
            timeLineChartPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 775, Short.MAX_VALUE)
        );
        timeLineChartPanelLayout.setVerticalGroup(
            timeLineChartPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 259, Short.MAX_VALUE)
        );

        tabbedPane.addTab(resourceMap.getString("timeLineChartPanel.TabConstraints.tabTitle"), timeLineChartPanel); // NOI18N

        rebootButton.setAction(actionMap.get("rebootNetwork")); // NOI18N
        rebootButton.setText(resourceMap.getString("rebootButton.text")); // NOI18N
        rebootButton.setName("rebootButton"); // NOI18N

        netStatusText.setEditable(false);
        netStatusText.setText(resourceMap.getString("netStatusText.text")); // NOI18N
        netStatusText.setName("netStatusText"); // NOI18N

        jLabel3.setText(resourceMap.getString("jLabel3.text")); // NOI18N
        jLabel3.setName("jLabel3"); // NOI18N

        jButton1.setAction(actionMap.get("dataLoad")); // NOI18N
        jButton1.setText(resourceMap.getString("jButton1.text")); // NOI18N
        jButton1.setName("jButton1"); // NOI18N

        numberOfKeys.setText(resourceMap.getString("numberOfKeys.text")); // NOI18N
        numberOfKeys.setName("numberOfKeys"); // NOI18N

        jLabel4.setText(resourceMap.getString("jLabel4.text")); // NOI18N
        jLabel4.setName("jLabel4"); // NOI18N

        javax.swing.GroupLayout mainPanelLayout = new javax.swing.GroupLayout(mainPanel);
        mainPanel.setLayout(mainPanelLayout);
        mainPanelLayout.setHorizontalGroup(
            mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(mainPanelLayout.createSequentialGroup()
                .addGap(529, 529, 529)
                .addComponent(netStatusText, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(751, Short.MAX_VALUE))
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, mainPanelLayout.createSequentialGroup()
                .addGap(86, 86, 86)
                .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(tabbedPane, javax.swing.GroupLayout.Alignment.TRAILING, 0, 0, Short.MAX_VALUE)
                    .addGroup(mainPanelLayout.createSequentialGroup()
                        .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addGroup(javax.swing.GroupLayout.Alignment.LEADING, mainPanelLayout.createSequentialGroup()
                                .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addGroup(mainPanelLayout.createSequentialGroup()
                                        .addGap(50, 50, 50)
                                        .addComponent(jLabel2))
                                    .addComponent(jLabel4))
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                                    .addGroup(mainPanelLayout.createSequentialGroup()
                                        .addComponent(numberOfKeys, javax.swing.GroupLayout.PREFERRED_SIZE, 72, javax.swing.GroupLayout.PREFERRED_SIZE)
                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 91, Short.MAX_VALUE)
                                        .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 69, javax.swing.GroupLayout.PREFERRED_SIZE))
                                    .addComponent(ServerList, javax.swing.GroupLayout.Alignment.LEADING, 0, 232, Short.MAX_VALUE)))
                            .addGroup(mainPanelLayout.createSequentialGroup()
                                .addComponent(initializeButton)
                                .addGap(18, 18, 18)
                                .addComponent(shutdownNodeButton)
                                .addGap(18, 18, 18)
                                .addComponent(jButton5, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE)))
                        .addGap(65, 65, 65)
                        .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addGroup(mainPanelLayout.createSequentialGroup()
                                .addGap(1, 1, 1)
                                .addComponent(evaluateButton)
                                .addGap(18, 18, 18)
                                .addComponent(viewNetInforButton, javax.swing.GroupLayout.PREFERRED_SIZE, 82, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addGap(32, 32, 32)
                                .addComponent(rebootButton)
                                .addGap(18, 18, 18)
                                .addComponent(clearButton, javax.swing.GroupLayout.PREFERRED_SIZE, 67, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addComponent(jLabel1)
                            .addComponent(jLabel3)
                            .addComponent(jScrollPane1))))
                .addGap(504, 504, 504))
        );

        mainPanelLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {clearButton, evaluateButton, rebootButton, viewNetInforButton});

        mainPanelLayout.setVerticalGroup(
            mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(mainPanelLayout.createSequentialGroup()
                .addGap(34, 34, 34)
                .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(netStatusText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel3))
                .addGap(35, 35, 35)
                .addComponent(jLabel1)
                .addGap(18, 18, 18)
                .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(mainPanelLayout.createSequentialGroup()
                        .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jButton5)
                            .addComponent(shutdownNodeButton)
                            .addComponent(initializeButton))
                        .addGap(36, 36, 36)
                        .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(ServerList, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jLabel2))
                        .addGap(34, 34, 34)
                        .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jButton1)
                            .addComponent(numberOfKeys, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jLabel4)))
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 163, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(evaluateButton)
                        .addComponent(viewNetInforButton))
                    .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(clearButton)
                        .addComponent(rebootButton)))
                .addGap(18, 18, 18)
                .addComponent(tabbedPane, javax.swing.GroupLayout.PREFERRED_SIZE, 287, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(28, Short.MAX_VALUE))
        );

        menuBar.setName("menuBar"); // NOI18N

        fileMenu.setText(resourceMap.getString("fileMenu.text")); // NOI18N
        fileMenu.setName("fileMenu"); // NOI18N

        exitMenuItem.setAction(actionMap.get("quit")); // NOI18N
        exitMenuItem.setName("exitMenuItem"); // NOI18N
        fileMenu.add(exitMenuItem);

        menuBar.add(fileMenu);

        helpMenu.setText(resourceMap.getString("helpMenu.text")); // NOI18N
        helpMenu.setName("helpMenu"); // NOI18N

        aboutMenuItem.setAction(actionMap.get("showAboutBox")); // NOI18N
        aboutMenuItem.setName("aboutMenuItem"); // NOI18N
        helpMenu.add(aboutMenuItem);

        menuBar.add(helpMenu);

        statusPanel.setName("statusPanel"); // NOI18N

        statusPanelSeparator.setName("statusPanelSeparator"); // NOI18N

        statusMessageLabel.setName("statusMessageLabel"); // NOI18N

        statusAnimationLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        statusAnimationLabel.setName("statusAnimationLabel"); // NOI18N

        progressBar.setName("progressBar"); // NOI18N

        javax.swing.GroupLayout statusPanelLayout = new javax.swing.GroupLayout(statusPanel);
        statusPanel.setLayout(statusPanelLayout);
        statusPanelLayout.setHorizontalGroup(
            statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(statusPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(statusMessageLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 1210, Short.MAX_VALUE)
                .addComponent(statusAnimationLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
            .addComponent(statusPanelSeparator, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 1370, Short.MAX_VALUE)
        );
        statusPanelLayout.setVerticalGroup(
            statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, statusPanelLayout.createSequentialGroup()
                .addComponent(statusPanelSeparator, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 27, Short.MAX_VALUE)
                .addGroup(statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, statusPanelLayout.createSequentialGroup()
                        .addGroup(statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(statusMessageLabel)
                            .addComponent(statusAnimationLabel))
                        .addGap(25, 25, 25))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, statusPanelLayout.createSequentialGroup()
                        .addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addContainerGap())))
        );

        setComponent(mainPanel);
        setMenuBar(menuBar);
        setStatusBar(statusPanel);
    }// </editor-fold>//GEN-END:initComponents

    @Action
    public void initialize() {
        this.consoleTextArea.append("initializing....");
        this.consoleTextArea.append("\n");
        SystemConfiguration config = Util.loadConfig();
        int numberOfNode = config.getNumberOfPhysicalNode();
        int subsNode = config.getSubstituteNodes();
        for (int i = 0; i < numberOfNode; i++) {
            this.ServerList.addItem("Server " + i);
        }
        for(int i = numberOfNode; i < subsNode + numberOfNode; i ++){
            this.ServerList.addItem("Substitute Server " + i);
        }
        //evaluate shema
        //identityIndex = config.getSimulatedData();
        netCtrl = new NetworkControl(config);
        netCtrl.initialize();
        this.consoleTextArea.append("initialized.");
        this.consoleTextArea.append("\n");
        RealSimulator rs = new RealSimulator(netCtrl);
        Thread autoThread = new Thread(rs);
        autoThread.start();

//        RealSimulator rs = new RealSimulator(netCtrl);
//        Thread autoThread1 = new Thread(rs, true);
//        autoThread.start();
        
        this.netStatusText.setText("AVAILABLE");
        this.identityIdx = config.getSimulatedData();
        this.netCtrl.addObserver(this);

        ChartMonitor cm = new ChartMonitor(netCtrl, this.timeLineChartPanel);
        Thread cmThread = new Thread(cm);
        cmThread.start();
        
    }

    @Action
    public void shutdownNode() {
        this.consoleTextArea.append("node is shutting down...");
        this.consoleTextArea.append("\n");
        String nodeId = (String) this.ServerList.getSelectedItem();
        int nodeIndex = Integer.valueOf(nodeId.substring(6).trim());
        netCtrl.shutdown(nodeIndex);
        if(netCtrl.getNetworkStatus() == Fallible.HEAVYLOAD){
            this.netStatusText.setText("heavy load found");
        }
        this.consoleTextArea.append("shutdown completed.");
        this.consoleTextArea.append("\n");
    }

    @Action
    public void evaluate() {
        this.consoleTextArea.append("network statistic \n");
        StatisticParameters param = this.netCtrl.statistic();
        this.consoleTextArea.append("std % " + String.valueOf(param.getStandardDeviation()) + "\n");
        this.consoleTextArea.append("total load  " + String.valueOf(param.getTotalLoad()) + " \n");
        this.consoleTextArea.append("=====================================" + "\n");
//        this.consoleTextArea.append("\n");

        //show chart
        EvaluatedParameters parm = this.netCtrl.evaluate();
        this.generateChart("chart", parm.getNodeParams());
    }

    public void generateChart(String title, Map<Long, NodeParameters> prms) {

        //super(title);
        ChartRender rd = new ChartRender("abc");

        XYSeries dataSeries = new XYSeries(0); //pass a key for this serie
        for (Long k : prms.keySet()) {
            long load = prms.get(k).getLoad();
            double averageLoadPerNode = load / prms.get(k).getCapacity();
            dataSeries.add((double) k, averageLoadPerNode);
            //replace by our node parameters
        }
        XYSeriesCollection xyDataset = new XYSeriesCollection();
        xyDataset.addSeries(dataSeries);
        JFreeChart chart = rd.createChart(xyDataset);
        ChartPanel cp = new ChartPanel(chart);
        chartPanel.setPreferredSize(new java.awt.Dimension(500, 150));

        this.chartPanel.setLayout(new java.awt.BorderLayout());
        chartPanel.removeAll();
        chartPanel.add(cp, BorderLayout.CENTER);
        chartPanel.validate();
//        chartPanel.(true);
//        chartPanel.setHorizontalAxisTrace(true);
        //setContentPane(chartPanel);

    }

    @Action
    public void clearConsole() {
//        this.consoleTextArea.;
        this.consoleTextArea.setText("");
    }

    @Action
    public void rebootNetwork() {
        this.netCtrl = null;
        this.clearConsole();
        this.consoleTextArea.append("reboot network..." + "\n");
        this.initialize();
        this.consoleTextArea.append("reboot network finished" + "\n");

    }

    @Action
    public void joinNode() {
        try {
            String serverIdStr = this.ServerList.getSelectedItem().toString();
            if(serverIdStr.contains("Substitute")){
                //join substitute nodes
                //manually or when overload found
                serverIdStr = serverIdStr.substring(17);
                this.netCtrl.lookupAndJoin(Integer.valueOf(serverIdStr));
                return;
            }
            serverIdStr = serverIdStr.substring(7);
//            this.netCtrl.lookupAndJoin(node);
            this.netCtrl.lookupAndJoin(Integer.valueOf(serverIdStr));
        } catch (Exception ex) {
            Logger.getLogger(RamStorageView.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Action
    public void viewNetInfor() {
        Map<Long, VirtualNode> net = netCtrl.printOut();
        int i = 0;
        for (Long k : net.keySet()) {
            this.vNodeTable.getModel().setValueAt(k, i, 0);
            this.vNodeTable.getModel().setValueAt(net.get(k).getpNode().getID(), i, 1);
            i++;
        }
        int k = 0;
        for (PhysicalNode node : this.netCtrl.nodes) {
            this.netInforTable.getModel().setValueAt(node.getID(), k, 0);
            this.netInforTable.getModel().setValueAt(node.getState(), k, 1);
            this.netInforTable.getModel().setValueAt(node.getLoad(), k, 2);
            this.netInforTable.getModel().setValueAt(node.getNumberOfVirtualNode(), k, 3);
            this.netInforTable.getModel().setValueAt(node.getVirtualNodeIds().toString(), k, 4);
            this.netInforTable.getModel().setValueAt(node.getLoad() / node.getNumberOfVirtualNode(), k, 5);
            k++;
        }

    }

    @Action
    public void dataLoad() {
        String text = this.numberOfKeys.getText();
        this.netCtrl.loadData(text, identityIdx);
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JComboBox ServerList;
    private javax.swing.JPanel chartPanel;
    private javax.swing.JButton clearButton;
    private javax.swing.JTextArea consoleTextArea;
    private javax.swing.JButton evaluateButton;
    private javax.swing.JButton initializeButton;
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton5;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JPanel mainPanel;
    private javax.swing.JMenuBar menuBar;
    private javax.swing.JPanel netInforPanel;
    private javax.swing.JTable netInforTable;
    private javax.swing.JTextField netStatusText;
    private javax.swing.JTextField numberOfKeys;
    private javax.swing.JProgressBar progressBar;
    private javax.swing.JButton rebootButton;
    private javax.swing.JButton shutdownNodeButton;
    private javax.swing.JLabel statusAnimationLabel;
    private javax.swing.JLabel statusMessageLabel;
    private javax.swing.JPanel statusPanel;
    private javax.swing.JTabbedPane tabbedPane;
    private javax.swing.JPanel timeLineChartPanel;
    private javax.swing.JTable vNodeTable;
    private javax.swing.JButton viewNetInforButton;
    // End of variables declaration//GEN-END:variables
    private NetworkControl netCtrl = null;
    private final Timer messageTimer;
    private final Timer busyIconTimer;
    private final Icon idleIcon;
    private final Icon[] busyIcons = new Icon[15];
    private int busyIconIndex = 0;
    private JDialog aboutBox;

    public void update(Observable o, Object arg) {
//        throw new UnsupportedOperationException("Not supported yet.");
        if(o instanceof NetworkControl){
            if(arg != null){
                if(arg instanceof StatisticParameters){
                    StatisticParameters stats = (StatisticParameters)arg;
                    statsKeepTrack.add(stats);
                }
                else if(arg instanceof String){
                    this.netStatusText.setText((String)arg);
                }
            }
            SortedMap<Minute, Double> ids = new TreeMap<Minute, Double>();
            for(int i = 0; i < statsKeepTrack.size(); i++){
                ids.put(new Minute(),statsKeepTrack.get(i).getStandardDeviation());
            }
            ChartRender rd = new ChartRender("Time Line Std");
            ChartPanel cp = new ChartPanel(rd.createTimeSeriesChart(ids));
            chartPanel.setPreferredSize(new java.awt.Dimension(500, 150));
            this.chartPanel.setLayout(new java.awt.BorderLayout());
            chartPanel.removeAll();
            chartPanel.add(cp, BorderLayout.CENTER);
            chartPanel.validate();
        }
    }
}
